//
//  QKLoopBanner.m
//  Pods
//
//  Created by ChiCo on 2018/6/2.
//

#import "QKLoopBanner.h"

@interface QKLoopBanner () <UIScrollViewDelegate>

@property (nonatomic,strong) UIScrollView *bodyView;
@property (nonatomic,strong) UIImageView *leftImageView;
@property (nonatomic,strong) UIImageView *centerImageView;
@property (nonatomic,strong) UIImageView *rightImageView;
@property (nonatomic,strong) UIPageControl *pageControl;

@property (nonatomic,assign) NSUInteger page;
@property (nonatomic,assign) NSUInteger imgesCount;
@property (nonatomic,assign)NSTimeInterval loopSpace;

@property (nonatomic,strong)NSTimer *timer;
@end

@implementation QKLoopBanner

#pragma mark - init
- (instancetype)initWithFrame:(CGRect)frame loopSpace:(NSTimeInterval )loopSpace{
    self = [super initWithFrame:frame];
    if (self) {
        self.loopSpace = loopSpace;
        [self setupViews];
        [self addObservers];
    }
    return self;
}
- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.loopSpace = 2.f;
        [self setupViews];
        [self addObservers];
    }
    return self;
}


- (void)setupViews {
    [self.bodyView addSubview:self.leftImageView];
    [self.bodyView addSubview:self.centerImageView];
    [self.bodyView addSubview:self.rightImageView];
    [self addSubview:self.bodyView];
    [self addSubview:self.pageControl];
    
    CGRect rect = self.frame;
    rect.origin = CGPointZero;
    self.bodyView.frame = rect;
    CGFloat imageWidth = rect.size.width;
    CGFloat imageHeight = rect.size.height;
    self.leftImageView.frame    = CGRectMake(imageWidth * 0, 0, imageWidth, imageHeight);
    self.centerImageView.frame  = CGRectMake(imageWidth * 1, 0, imageWidth, imageHeight);
    self.rightImageView.frame   = CGRectMake(imageWidth * 2, 0, imageWidth, imageHeight);
    self.bodyView.contentSize = CGSizeMake(imageWidth * 3, 0);
    [self.bodyView setContentOffset:CGPointMake(imageWidth, 0)];
}


- (NSTimer *)timer {
    if (!_timer) {
        _timer = [NSTimer scheduledTimerWithTimeInterval:self.loopSpace
                                                            target:self
                                                          selector:@selector(scrollTimerDidFired:)
                                                          userInfo:nil
                                                           repeats:YES];
        [_timer setFireDate:[NSDate distantFuture]];
    }
    return _timer;
}
- (UIScrollView *)bodyView {
    if (!_bodyView) {
        _bodyView = [[UIScrollView alloc] init];
        _bodyView.delegate = self;
        _bodyView.pagingEnabled = YES;
        _bodyView.showsHorizontalScrollIndicator = NO;
        _bodyView.showsVerticalScrollIndicator = NO;
    }
    return _bodyView;
}
- (UIImageView *)leftImageView {
    if (!_leftImageView) {
        _leftImageView = [[UIImageView alloc] init];
        _leftImageView.contentMode = UIViewContentModeScaleAspectFit;
    }
    return _leftImageView;
}
- (UIImageView *)centerImageView {
    if (!_centerImageView) {
        _centerImageView = [[UIImageView alloc] init];
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(imageClicked:)];
        [_centerImageView addGestureRecognizer:tap];
        _centerImageView.contentMode = UIViewContentModeScaleAspectFit;
    }
    return _centerImageView;
}
- (UIImageView *)rightImageView {
    if (!_rightImageView) {
        _rightImageView = [[UIImageView alloc] init];
        _rightImageView.contentMode = UIViewContentModeScaleAspectFit;
    }
    return _rightImageView;
}



#pragma mark - data source
- (void)setDataSource:(id<QKLoopBannerDataSource>)dataSource {
    
    _dataSource = dataSource;
    if (_dataSource) {
        self.imgesCount = [dataSource numberOfImagesInLoopBanner:self];
    }
    
}
- (void)setPageControl:(UIPageControl *)pageControl {
    if (!pageControl && _pageControl) {
        [_pageControl removeFromSuperview];
        _pageControl = nil;
    } else {
        _pageControl = pageControl;
    }
}

- (void)reloadData {
    self.imgesCount = [self.dataSource numberOfImagesInLoopBanner:self];
}
- (void)setImgesCount:(NSUInteger)imgesCount {
    _imgesCount = imgesCount;
    _page = 0;
    switch (imgesCount) {
        case 0:
        {
            [self.leftImageView setImage:nil];
            [self.centerImageView setImage:nil];
            [self.rightImageView setImage:nil];
            [self.bodyView setScrollEnabled:NO];
            [self.centerImageView setUserInteractionEnabled:NO];
            if (self.pageControl) {
                [self.pageControl removeFromSuperview];
                self.pageControl = nil;
            }
        }
            break;
        case 1:
        {
            [self.centerImageView setImage:nil];
            [self.rightImageView setImage:nil];
            [self changeToCenter];
            [self.dataSource loopBanner:self reloadImageView:self.centerImageView index:0];
            [self.centerImageView setUserInteractionEnabled:YES];
            [self.bodyView setScrollEnabled:NO];
            if (self.pageControl) {
                [self.pageControl removeFromSuperview];
                self.pageControl = nil;
            }
        }
            break;
            
        default:
        {
            [self.bodyView setScrollEnabled:YES];
            [self.dataSource loopBanner:self reloadImageView:self.rightImageView index:imgesCount-1];
            [self.dataSource loopBanner:self reloadImageView:self.centerImageView index:0];
            [self.dataSource loopBanner:self reloadImageView:self.rightImageView index:1];
            if ([self.dataSource respondsToSelector:@selector(loopBanner:chanedPage:)]) {
                [self.dataSource loopBanner:self chanedPage:_page];
            }
            [self.centerImageView setUserInteractionEnabled:YES];
            [self.timer setFireDate:[NSDate dateWithTimeIntervalSinceNow:self.loopSpace]];
            if ([self.dataSource respondsToSelector:@selector(pageControlOfloopBanner:)]) {
                self.pageControl = [self.dataSource pageControlOfloopBanner:self];
                [self addSubview:self.pageControl];
                [self.pageControl setNumberOfPages:imgesCount];
            }
        }
            break;
    }
}

#pragma mark - bodyView change contentOffset
- (void)addObservers {
    [self.bodyView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
}

- (void)removeObservers {
    [self.bodyView removeObserver:self forKeyPath:@"contentOffset"];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    if ([keyPath isEqualToString:@"contentOffset"]) {
        [self caculatePage];
    }
}

#pragma mark - count page
- (void)caculatePage {
    if (self.imgesCount > 0) {
        CGFloat pointX = self.bodyView.contentOffset.x;
        
        // judge critical value，first and third imageView's contentoffset
        // last to first or first to last
        CGFloat criticalValue = .2f;
        
     
        if (pointX > 2 * CGRectGetWidth(self.bodyView.bounds) - criticalValue) {
            //centerImage to rightImage(next page)
            // {An | Sn = 1,2,3...n} == {An | Sn = n}
            // {Bn | Sn = 2,3,..n,1} == {Bn | Sn = (n + 1)%n }
            self.page = (self.page + 1) % self.imgesCount;
        } else if (pointX < criticalValue) {
            //scroll to leftImage(previous page)
            // + self.imgesCount mod case for self.page == 0
            self.page = (self.page + self.imgesCount - 1) % self.imgesCount;
        }
    }
}
- (void)setPage:(NSUInteger)page {
    _page = page;
    NSUInteger leftIndex = (_page + self.imgesCount - 1) % self.imgesCount;
    NSUInteger rightIndex= (_page + 1) % self.imgesCount;
    [self.dataSource loopBanner:self reloadImageView:self.leftImageView index:leftIndex];
    [self.dataSource loopBanner:self reloadImageView:self.centerImageView index:_page];
    [self.dataSource loopBanner:self reloadImageView:self.rightImageView index:rightIndex];
    if ([self.dataSource respondsToSelector:@selector(loopBanner:chanedPage:)]) {
        [self.dataSource loopBanner:self chanedPage:_page];
    }
    [self changeToCenter];
    [self.pageControl setCurrentPage:_page];
}
- (void)changeToCenter {
    self.bodyView.contentOffset = CGPointMake(CGRectGetWidth(self.bodyView.bounds), 0);
}

#pragma mark - scroll delegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    if (self.imgesCount > 1) {
        [self.timer setFireDate:[NSDate distantFuture]];
    }
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    if (self.imgesCount > 1) {
        [self.timer setFireDate:[NSDate dateWithTimeIntervalSinceNow:self.loopSpace]];
    }
}
#pragma mark - action
- (void)imageClicked:(UITapGestureRecognizer *)tap {
    if ([self.delegate respondsToSelector:@selector(loopBanner:didSelectedItem:index:)]) {
        [self.delegate loopBanner:self didSelectedItem:self.centerImageView index:self.page];
    }
}
#pragma mark - timer action
- (void)scrollTimerDidFired:(NSTimer *)timer {
   
    CGFloat criticalValue = .2f;
    if (self.bodyView.contentOffset.x < CGRectGetWidth(self.bodyView.bounds) - criticalValue || self.bodyView.contentOffset.x > CGRectGetWidth(self.bodyView.bounds) + criticalValue) {
        [self changeToCenter];
    }
    CGPoint newOffset = CGPointMake(self.bodyView.contentOffset.x + CGRectGetWidth(self.bodyView.bounds), self.bodyView.contentOffset.y);
    [self.bodyView setContentOffset:newOffset animated:YES];
}

#pragma mark - memeory
- (void)removeFromSuperview {
    if (self.timer) {
        [self.timer invalidate];
        self.timer = nil;
    }
}
- (void)dealloc {
    [self removeObservers];
}
@end
